#pragma once

#include "utils/ring_buffer.h"
#include "utils/memory_pool.h"
#include "utils/simd_math.h"
#include "utils/simd_math_ext.h"
#include <string>
#include <unordered_map>
#include <memory>
#include <vector>
#include <mutex>
#include <algorithm>

namespace hft {

/**
 * @brief 高度优化的价格历史管理器
 * 
 * 这个类使用RingBuffer、内存池和SIMD指令来优化价格历史数据的存储和计算。
 * 它提供了高效的移动平均、标准差等计算功能，适合高频交易场景。
 */
class OptimizedPriceHistory {
public:
    /**
     * @brief 构造函数
     * @param capacity 历史数据容量
     */
    explicit OptimizedPriceHistory(size_t capacity = 1000)
        : prices_(capacity)
        , sum_(0.0)
        , sum_sq_(0.0)
        , count_(0)
        , capacity_(capacity) {
    }
    
    /**
     * @brief 添加价格数据
     * @param price 价格
     */
    void addPrice(double price) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        if (count_ == capacity_) {
            // 缓冲区已满，移除最旧的价格
            double old_price = prices_[0];
            sum_ -= old_price;
            sum_sq_ -= old_price * old_price;
        } else {
            // 缓冲区未满，增加计数
            ++count_;
        }
        
        // 添加新价格
        prices_.push_back(price);
        sum_ += price;
        sum_sq_ += price * price;
    }
    
    /**
     * @brief 获取最新价格
     * @return 最新价格
     */
    double getLatestPrice() const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ == 0) return 0.0;
        return prices_[count_ - 1];
    }
    
    /**
     * @brief 获取指定位置的价格
     * @param index 索引（0表示最旧的价格）
     * @return 价格
     */
    double getPrice(size_t index) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (index >= count_) return 0.0;
        return prices_[index];
    }
    
    /**
     * @brief 获取价格数组
     * @return 价格数组
     */
    std::vector<double> getPrices() const {
        std::lock_guard<std::mutex> lock(mutex_);
        std::vector<double> result(count_);
        for (size_t i = 0; i < count_; ++i) {
            result[i] = prices_[i];
        }
        return result;
    }
    
    /**
     * @brief 获取价格数量
     * @return 价格数量
     */
    size_t getCount() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return count_;
    }
    
    /**
     * @brief 获取容量
     * @return 容量
     */
    size_t getCapacity() const {
        return capacity_;
    }
    
    /**
     * @brief 清空价格历史
     */
    void clear() {
        std::lock_guard<std::mutex> lock(mutex_);
        prices_.clear();
        sum_ = 0.0;
        sum_sq_ = 0.0;
        count_ = 0;
    }
    
    /**
     * @brief 计算简单移动平均
     * @param period 周期
     * @return 移动平均值
     */
    double calculateSMA(size_t period) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ < period || period == 0) return 0.0;
        
        // 使用SIMD优化的求和
        const double* data = prices_.data() + (count_ - period);
        return utils::simd::mean(data, period);
    }
    
    /**
     * @brief 计算指数移动平均
     * @param alpha 平滑因子
     * @return 指数移动平均值
     */
    double calculateEMA(double alpha) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ == 0) return 0.0;
        if (alpha <= 0.0 || alpha > 1.0) alpha = 0.1; // 默认值
        
        std::vector<double> result(count_);
        utils::simd::exponentialMovingAverage(prices_.data(), count_, alpha, result.data());
        return result.back();
    }
    
    /**
     * @brief 计算标准差
     * @param period 周期
     * @return 标准差
     */
    double calculateStdDev(size_t period) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ < period || period == 0) return 0.0;
        
        // 使用SIMD优化的标准差计算
        const double* data = prices_.data() + (count_ - period);
        return utils::simd::stdDev(data, period);
    }
    
    /**
     * @brief 计算Z-Score（标准分数）
     * @param period 周期
     * @return Z-Score
     */
    double calculateZScore(size_t period) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ < period || period == 0) return 0.0;
        
        double latest = prices_[count_ - 1];
        double mean = calculateSMA(period);
        double std_dev = calculateStdDev(period);
        
        if (std_dev < 1e-10) return 0.0;
        return (latest - mean) / std_dev;
    }
    
    /**
     * @brief 计算布林带
     * @param period 周期
     * @param deviation 标准差倍数
     * @return {中轨, 上轨, 下轨}
     */
    std::tuple<double, double, double> calculateBollingerBands(size_t period, double deviation = 2.0) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ < period || period == 0) return {0.0, 0.0, 0.0};
        
        double middle = calculateSMA(period);
        double std_dev = calculateStdDev(period);
        
        double upper = middle + deviation * std_dev;
        double lower = middle - deviation * std_dev;
        
        return {middle, upper, lower};
    }
    
    /**
     * @brief 计算相对强弱指标（RSI）
     * @param period 周期
     * @return RSI值
     */
    double calculateRSI(size_t period) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ <= period + 1) return 50.0; // 默认值
        
        std::vector<double> result(count_ - 1);
        utils::simd::relativeStrengthIndex(prices_.data(), count_, period, result.data());
        return result.back();
    }
    
    /**
     * @brief 计算MACD
     * @param fast_period 快线周期
     * @param slow_period 慢线周期
     * @param signal_period 信号线周期
     * @return {MACD线, 信号线, 柱状图}
     */
    std::tuple<double, double, double> calculateMACD(size_t fast_period = 12, 
                                                   size_t slow_period = 26, 
                                                   size_t signal_period = 9) const {
        std::lock_guard<std::mutex> lock(mutex_);
        if (count_ <= slow_period) return {0.0, 0.0, 0.0};
        
        std::vector<double> macd_line(count_);
        std::vector<double> signal_line(count_);
        std::vector<double> histogram(count_);
        
        utils::simd::macd(prices_.data(), count_, fast_period, slow_period, signal_period,
                        macd_line.data(), signal_line.data(), histogram.data());
        
        return {macd_line.back(), signal_line.back(), histogram.back()};
    }
    
private:
    utils::RingBuffer<double> prices_;  // 价格历史
    double sum_;                        // 价格之和
    double sum_sq_;                     // 价格平方和
    size_t count_;                      // 当前价格数量
    size_t capacity_;                   // 容量
    mutable std::mutex mutex_;          // 互斥锁
};

/**
 * @brief 多品种价格历史管理器
 * 
 * 这个类管理多个交易品种的价格历史，使用哈希表快速查找特定品种的价格历史。
 */
class OptimizedMultiPriceHistory {
public:
    /**
     * @brief 构造函数
     * @param capacity 每个品种的历史数据容量
     */
    explicit OptimizedMultiPriceHistory(size_t capacity = 1000)
        : capacity_(capacity) {
    }
    
    /**
     * @brief 添加价格数据
     * @param symbol 交易品种
     * @param price 价格
     */
    void addPrice(const std::string& symbol, double price) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        auto it = price_histories_.find(symbol);
        if (it == price_histories_.end()) {
            // 创建新的价格历史
            auto history = std::make_shared<OptimizedPriceHistory>(capacity_);
            history->addPrice(price);
            price_histories_[symbol] = history;
        } else {
            // 添加到现有价格历史
            it->second->addPrice(price);
        }
    }
    
    /**
     * @brief 获取指定品种的价格历史
     * @param symbol 交易品种
     * @return 价格历史指针
     */
    std::shared_ptr<OptimizedPriceHistory> getPriceHistory(const std::string& symbol) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        auto it = price_histories_.find(symbol);
        if (it == price_histories_.end()) {
            return nullptr;
        }
        return it->second;
    }
    
    /**
     * @brief 获取所有交易品种
     * @return 交易品种列表
     */
    std::vector<std::string> getSymbols() const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        std::vector<std::string> symbols;
        symbols.reserve(price_histories_.size());
        
        for (const auto& pair : price_histories_) {
            symbols.push_back(pair.first);
        }
        
        return symbols;
    }
    
    /**
     * @brief 清空指定品种的价格历史
     * @param symbol 交易品种
     */
    void clear(const std::string& symbol) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        auto it = price_histories_.find(symbol);
        if (it != price_histories_.end()) {
            it->second->clear();
        }
    }
    
    /**
     * @brief 清空所有价格历史
     */
    void clearAll() {
        std::lock_guard<std::mutex> lock(mutex_);
        
        for (auto& pair : price_histories_) {
            pair.second->clear();
        }
    }
    
    /**
     * @brief 计算两个品种之间的相关系数
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @param period 周期
     * @return 相关系数
     */
    double calculateCorrelation(const std::string& symbol1, const std::string& symbol2, size_t period) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        auto it1 = price_histories_.find(symbol1);
        auto it2 = price_histories_.find(symbol2);
        
        if (it1 == price_histories_.end() || it2 == price_histories_.end()) {
            return 0.0;
        }
        
        auto& history1 = it1->second;
        auto& history2 = it2->second;
        
        size_t count1 = history1->getCount();
        size_t count2 = history2->getCount();
        
        if (count1 < period || count2 < period) {
            return 0.0;
        }
        
        // 获取最近period个价格
        std::vector<double> prices1 = history1->getPrices();
        std::vector<double> prices2 = history2->getPrices();
        
        // 确保使用相同长度的数据
        size_t start1 = (count1 > period) ? count1 - period : 0;
        size_t start2 = (count2 > period) ? count2 - period : 0;
        
        // 使用SIMD优化的相关系数计算
        return utils::simd::correlation(prices1.data() + start1, prices2.data() + start2, period);
    }
    
private:
    std::unordered_map<std::string, std::shared_ptr<OptimizedPriceHistory>> price_histories_;
    size_t capacity_;
    mutable std::mutex mutex_;
};

} // namespace hft